#pragma once

#include <map>
#include <string>
#include <memory>
#include <functional>

#include "gl_window.h"


class WindowFactory {
public:

    class Register {
    public:
        Register(const std::string &name, std::function<GlWindow *()> &&creator);
    };

    static WindowFactory &instance();

    void addCreator(const std::string &name, std::function<GlWindow *()> &&creator);

    std::unique_ptr<GlWindow> create(const std::string &name) const;

private:
    WindowFactory();

    ~WindowFactory();

private:
    std::map<std::string, std::function<GlWindow *()>> creators_;
};

#define REGISTER_WINDOW_IMPL(type) static const WindowFactory::Register gRegisterWindowImplFor##type(#type, [] { return new type; });
